<template>
  <div class="chart-wrapper">
    <chart
      :option="refChartOption"
      :style="{ height: `${chartHeight}` }"
      v-bind="$attrs"
      @zrender:click="pieRenderClickHandle"
    />
    <div class="title" style="margin-top: -10px">
      <slot name="title"></slot>
      <slot name="titles" v-if="currentTitle != ''">
        <span class="total">{{ currentTotal }}</span>
        <span style="color: rgba(233, 146, 32, 1)">{{ currentTitle }}</span>
      </slot>
    </div>
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, onMounted, PropType, ref, watch } from 'vue';
import { Chart, SeriesDataItem } from '@/components';
import { EChartOption } from 'echarts';
import { labelLineData } from '@/components/charts/util';
import { cloneDeep } from 'lodash';
type PieDataType = number[] | number[][] | EChartOption.SeriesPie.DataObject[];

const colors = [
  '#EB5B5B',
  '#E48648',
  '#E8F252',
  '#8BDB22',
  '#23BB23',
  '#22DBC8',
  '#54C0EE',
  '#3555F7',
  '#7975F1',
  '#A15FE3',
  '#A525E3',
  '#D820D2',
  '#E63298',
];

const colorTransparent = [
  'rgba(235, 91, 91, 40%)',
  'rgba(228, 134, 72, 40%)',
  'rgba(232, 242, 82, 40%)',
  'rgba(139, 219, 34, 40%)',
  'rgba(35, 187, 35, 40%)',
  'rgba(34, 219, 200, 40%)',
  'rgba(84, 192, 238, 40%)',
  'rgba(53, 85, 247, 40%)',
  'rgba(121, 117, 241, 40%)',
  'rgba(161, 95, 227, 40%)',
  'rgba(165, 37, 227, 40%)',
  'rgba(216, 32, 210, 40%)',
  'rgba(230, 50, 152, 40%)',
];

const option = {
  title: {
    zlevel: 0,
    text: '',
    top: 'center',
    left: '50%',
    textAlign: 'center',
    textStyle: {
      rich: {
        value: {
          color: '#666',
          fontSize: 20,
          fontWeight: 'bold',
          lineHeight: 20,
        },
        name: {
          color: '#909399',
          lineHeight: 20,
        },
      },
    },
  },
  tooltip: {
    // 悬停指示
    trigger: 'item',
    formatter: '{b}: {c} ({d}%)',
  },
  series: [
    {
      zlevel: 1,
      type: 'pie',
      clockwise: false, //饼图的扇区是否是顺时针排布
      minAngle: 2, //最小的扇区角度（0 ~ 360）
      radius: ['45%', '65%'],
      center: ['50%', '50%'],
      itemStyle: {},
      label: {
        normal: {
          show: true,
          formatter: '{b}\n {c}({d}%)', //自定义显示格式(b:name, c:value, d:百分比)
        },
      },
      data: [] as PieDataType,
    },
  ] as EChartOption.SeriesPie[],
};

export default defineComponent({
  props: {
    data: {
      type: Array as PropType<SeriesDataItem[]>,
      default: () => [],
    },
    height: {
      type: Number,
      default: 200,
    },
    fieldNames: {
      type: Object,
      default: () => ({
        name: 'name',
        value: 'value',
      }),
    },
    title: {
      type: String,
      default: '',
    },
    defalutOptions: {},
  },
  emits: ['zrender:click'],
  setup(props, { emit }) {
    const currentTitle = ref<string>(props.title);
    const currentTotal = ref<number>(0);
    const refChartOption = ref(option);
    const mergeOptions = () => {
      refChartOption.value = Object.assign({}, option, props.defalutOptions);
    };
    const chartHeight = computed(() => `${props.height}px`);
    // 总数
    const total = computed(() =>
      props.data.reduce((total, currentValue) => {
        return total + currentValue[props.fieldNames.value];
      }, 0),
    );

    const setChartOption = (data: any[]) => {
      const chartData = cloneDeep(data);
      const seriesData: EChartOption.SeriesPie.DataObject[] = [];
      let indexs = 0;
      chartData.forEach(item => {
        if (indexs === 13) {
          indexs = 0;
        }
        item.itemStyle = {};
        item.itemStyle.normal = {};
        item.itemStyle.emphasis = {};
        item.itemStyle.normal.borderColor = colors[indexs];
        item.itemStyle.normal.color = colorTransparent[indexs];
        item.itemStyle.emphasis.color = colors[indexs];

        indexs++;
        const name = item[props.fieldNames.name];
        const value = item[props.fieldNames.value];
        const seriesItem = {
          name,
          value,
        };
        Object.keys(item).forEach(
          o =>
            ![props.fieldNames.name, props.fieldNames.value].includes(o) &&
            (seriesItem[o] = item[o]),
        );

        seriesData.push(seriesItem);
      });

      refChartOption.value.series[0].data = labelLineData(seriesData, 5);
    };

    const pieRenderClickHandle = e => {
      emit('zrender:click', e);
    };

    watch(
      () => props.data,
      () => {
        currentTitle.value = props.title;
        currentTotal.value = total.value;
        mergeOptions();
        setChartOption(props.data);
      },
      {
        deep: true,
      },
    );

    onMounted(() => {
      currentTitle.value = props.title;
      currentTotal.value = total.value;
      mergeOptions();
      setChartOption(props.data);
    });
    return {
      currentTitle,
      currentTotal,
      chartHeight,
      refChartOption,
      setChartOption,
      pieRenderClickHandle,
    };
  },
  components: {
    Chart,
  },
});
</script>

<style lang="less" scoped>
.chart-wrapper {
  position: relative;
  .title {
    position: absolute;
    top: 50%;
    left: 50%;
    display: flex;
    flex-direction: column;
    align-items: center;
    color: #666;
    font-size: 18px;
    transform: translate(-50%, -50%);
  }
}
.total {
  color: rgba(233, 146, 32, 1);
  font-weight: bold;
  font-size: 50px;
}
</style>
